home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / libs / winlib-0.0 / winlib-0 / win / window.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-02  |  8.3 KB  |  331 lines

  1. /*
  2.  * WinLIB
  3.  * Window routines
  4.  */
  5.  
  6. #include <stdlib.h>
  7. #include "winlib.h"
  8. #include "internal.h"
  9. #include "config.h"
  10.  
  11. WIN *_wintree;
  12. int _moving_win, _has_win, _moving_idx;
  13.  
  14. int _winstruct_length(void)
  15. {
  16.     return(sizeof(struct _winstruct));
  17. }
  18.  
  19. void _top_window_link(void)
  20. {
  21.     while(_wintree->prev)
  22.     _wintree = _wintree->prev;
  23. }
  24.  
  25. void _bottom_window_link(void)
  26. {
  27.     while(_wintree->next)
  28.     _wintree = _wintree->next;
  29. }
  30.  
  31. void _create_window(int x, int y, int w, int h, char *title, int mode)
  32. {
  33.     int i;
  34.  
  35.     /* Create our window and work window structures */
  36.     _wintree->win = newwin(h, w, y, x);
  37.     _wintree->workwin = newwin(h - 2, w - 2, y + 1, x + 1);
  38.     _wintree->pan = new_panel(_wintree->win);
  39.     _wintree->workpan = new_panel(_wintree->workwin);
  40.  
  41.     /* Save window coordinate information */
  42.     _wintree->cur.x = x;    _wintree->orig.x = x;
  43.     _wintree->cur.y = y;    _wintree->orig.y = y;
  44.     _wintree->cur.w = w;    _wintree->orig.w = w;
  45.     _wintree->cur.h = h;    _wintree->orig.h = h;
  46.  
  47.     /* And let the work window become scrollable */
  48.     scrollok(_wintree->workwin, TRUE);
  49.  
  50.     /* Draw the borders */
  51.     for(i = 0; i < _wintree->win->_maxx; i++) {
  52.     mvwaddch(_wintree->win, 0, i, ACS_DHLINE);
  53.     mvwaddch(_wintree->win, _wintree->win->_maxy, i, ACS_DHLINE);
  54.     }
  55.  
  56.     for(i = 0; i < _wintree->win->_maxy; i++) {
  57.     mvwaddch(_wintree->win, i, 0, ACS_DVLINE);
  58.     mvwaddch(_wintree->win, i, _wintree->win->_maxx, ACS_DVLINE);
  59.     }
  60.  
  61.     /* Add the corners */
  62.     mvwaddch(_wintree->win, 0, 0, ACS_DULCORNER);
  63.     mvwaddch(_wintree->win, 0, _wintree->win->_maxx, ACS_DURCORNER);
  64.     mvwaddch(_wintree->win, _wintree->win->_maxy, 0, ACS_DLLCORNER);
  65.     mvwaddch(_wintree->win, _wintree->win->_maxy, _wintree->win->_maxx, ACS_DLRCORNER);
  66.  
  67.     /* And the title */
  68.     i = (_wintree->win->_maxx - strlen(title)) / 2;
  69.     mvwaddstr(_wintree->win, 0, i, title);
  70.  
  71.     /* Add a closer button if there is one */
  72.     if (mode & CLOSER) {
  73.     mvwaddch(_wintree->win, 0, 1, '[');
  74.     mvwaddch(_wintree->win, 0, 2, ACS_BULLET);
  75.     mvwaddch(_wintree->win, 0, 3, ']');
  76.     }
  77.  
  78.     /* Add a mover indicator around the title bar if you can move the window */
  79.     if (mode & MOVER) {
  80.     mvwaddch(_wintree->win, 0, i - 1, ' ');
  81.     mvwaddch(_wintree->win, 0, i - 2, '[');
  82.     mvwaddch(_wintree->win, 0, i + strlen(title), ' ');
  83.     mvwaddch(_wintree->win, 0, i + strlen(title) + 1, ']');
  84.     }
  85.  
  86.     i = 0;
  87.  
  88.     /* Put a minimizer button in */
  89.     if (mode & MINIMIZER) {
  90.     mvwaddch(_wintree->win, 0, _wintree->win->_maxx - 1, ']');
  91.     mvwaddch(_wintree->win, 0, _wintree->win->_maxx - 2, ACS_DARROW);
  92.     mvwaddch(_wintree->win, 0, _wintree->win->_maxx - 3, '[');
  93.     i = 3;
  94.     }
  95.  
  96.     /* And a maximizer */
  97.     if (mode & MAXIMIZER) {
  98.     mvwaddch(_wintree->win, 0, _wintree->win->_maxx - (1 + i), ']');
  99.     mvwaddch(_wintree->win, 0, _wintree->win->_maxx - (2 + i), ACS_UARROW);
  100.     mvwaddch(_wintree->win, 0, _wintree->win->_maxx - (3 + i), '[');
  101.     }
  102.  
  103.     /* And the sizer stuff */
  104.     if (mode & SIZER) {
  105.     mvwaddch(_wintree->win, 0, 0, ACS_ULCORNER);
  106.     mvwaddch(_wintree->win, 0, _wintree->win->_maxx, ACS_URCORNER);
  107.     mvwaddch(_wintree->win, _wintree->win->_maxy, 0, ACS_LLCORNER);
  108.     mvwaddch(_wintree->win, _wintree->win->_maxy, _wintree->win->_maxx, ACS_LRCORNER);
  109.     }
  110.  
  111.     if (_wintree->callback)
  112.     (_wintree->callback)(_wintree->workwin, WM_CREATED);
  113.  
  114.     Win_PlaySound(SOUND_OPEN);
  115. }
  116.  
  117. void _add_window_link(void)
  118. {
  119.     /* Allocate a new window structure for the next window */
  120.     _wintree->next = (WIN *) malloc(_winstruct_length());
  121.  
  122.     /* Point the previous window pointer of the next window here, so we
  123.        have a place to backtrack to. */
  124.     _wintree->next->prev = _wintree;
  125.  
  126.     /* Increase our global pointer to point to the new window */
  127.     _wintree = _wintree->next;
  128.  
  129.     /* And make sure this window can't go off into nowheresville */
  130.     _wintree->next = NULL;
  131. }
  132.  
  133. void _delete_window_link(void)
  134. {
  135.     if (_wintree->prev)
  136.     _wintree->prev->next = _wintree->next;
  137.  
  138.     if (_wintree->next)
  139.     _wintree->next->prev = _wintree->prev;
  140.  
  141.     free(_wintree);
  142.  
  143.     if (_wintree->prev)
  144.     _wintree = _wintree->prev;
  145.     else if (_wintree->next)
  146.     _wintree = _wintree->next;
  147.     else {
  148.     _wintree = (WIN *) malloc(sizeof(_winstruct_length()));
  149.     _wintree->prev = NULL;
  150.     _wintree->next = NULL;
  151.     }
  152. }
  153.  
  154. int _get_window_index(Gpm_Event *event)
  155. {
  156.     int idx = -1;
  157.  
  158.     if (_moving_idx == -1) {
  159.     _top_window_link();
  160.  
  161.     while(_wintree->next) {
  162.         if ((event->y >= _wintree->win->_begy) &&
  163.         (event->y <= (_wintree->win->_begy + _wintree->win->_maxy)) &&
  164.             (event->x >= _wintree->win->_begx) &&
  165.         (event->x <= (_wintree->win->_begx + _wintree->win->_maxx)))
  166.         idx = _wintree->index;
  167.  
  168.         _wintree = _wintree->next;
  169.     }
  170.     } else
  171.     idx = _moving_idx;
  172.  
  173.     return(idx);
  174. }
  175.  
  176. void _minimize_window(void)
  177. {
  178.     Win_PlaySound(SOUND_MINIMIZE);
  179.     if (_wintree->callback)
  180.     (_wintree->callback)(_wintree->workwin, WM_MINIMIZED);
  181. }
  182.  
  183. void _maximize_window(void)
  184. {
  185.     Win_PlaySound(SOUND_MAXIMIZE);
  186.     if (_wintree->callback)
  187.     (_wintree->callback)(_wintree->workwin, WM_MAXIMIZED);
  188. }
  189.  
  190. void _move_window(Gpm_Event *event)
  191. {
  192.     int x = event->x, y = event->y;
  193.  
  194.     x -= _xoffset;
  195.  
  196.     if (y > (_main_win->_maxy - _wintree->win->_maxy + 1))
  197.     y = (_main_win->_maxy - _wintree->win->_maxy + 1);
  198.     if (x > (_main_win->_maxx - _wintree->win->_maxx))
  199.     x = (_main_win->_maxx - _wintree->win->_maxx);
  200.  
  201.     if (x < 0)
  202.     x = 0;
  203.  
  204.     if (y < 1)
  205.     y = 1;
  206.  
  207.     _wintree->cur.x = x;
  208.     _wintree->cur.y = y;
  209.  
  210.     move_panel(_wintree->pan, y, x);
  211.     move_panel(_wintree->workpan, y + 1, x + 1);
  212.  
  213.     if (_wintree->callback)
  214.     (_wintree->callback)(_wintree->workwin, WM_MOVED);
  215. }
  216.  
  217. /* Ugh!  This is sloppy code, but it works quite well.  I need to optimize
  218.    this a bit and make it more readable.  :) */
  219. void _handle_window_coords(Gpm_Event *event)
  220. {
  221.     int i = 1, x = 1;
  222.  
  223.     if (_wintree->mode & CLOSER) {
  224.     if ((event->x == _wintree->win->_begx + 2) &&
  225.         (event->y == _wintree->win->_begy) &&
  226.         (_moving_win == FALSE) &&
  227.         (event->buttons & GPM_B_LEFT)) {
  228.         if (_wintree->callback)
  229.         (_wintree->callback)(WM_DELETED);
  230.         Win_PlaySound(SOUND_CLOSE);
  231.         del_panel(_wintree->pan);
  232.         del_panel(_wintree->workpan);
  233.         delwin(_wintree->win);
  234.         delwin(_wintree->workwin);
  235.         _delete_window_link();
  236.     }
  237.  
  238.     x = 4;
  239.     }
  240.  
  241.     if (_wintree->mode & MINIMIZER) {
  242.     if ((event->x == (_wintree->win->_begx + _wintree->win->_maxx) - 2) &&
  243.         (event->y == _wintree->win->_begy) &&
  244.         (_moving_win == FALSE) &&
  245.         (event->buttons & GPM_B_LEFT) &&
  246.         (!(event->type & (GPM_DRAG | GPM_UP))))
  247.         _minimize_window();
  248.  
  249.     i = 4;
  250.     }
  251.  
  252.     if (_wintree->mode & MAXIMIZER) {
  253.     if ((event->x == (_wintree->win->_begx + _wintree->win->_maxx) - (1 + i)) &&
  254.         (event->y == _wintree->win->_begy) &&
  255.         (_moving_win == FALSE) &&
  256.         (event->buttons & GPM_B_LEFT) &&
  257.         (!(event->type & (GPM_DRAG | GPM_UP))))
  258.         _maximize_window();
  259.     }
  260.  
  261.     if ((_wintree->mode & MOVER) || (_moving_win)) {
  262.     if ((event->x >= (_wintree->win->_begx + x)) &&
  263.         (event->x <= (_wintree->win->_begx + _wintree->win->_maxx - i)) &&
  264.         (event->y == _wintree->win->_begy) &&
  265.         (_moving_win == FALSE) &&
  266.         (event->buttons & GPM_B_LEFT) &&
  267.         (event->type & GPM_DOWN)) {
  268.         _xoffset = event->x - _wintree->win->_begx;
  269.         _moving_win = TRUE;
  270.         _moving_idx = _wintree->index;
  271.     }
  272.  
  273.     if ((_moving_win) && (event->buttons & GPM_B_LEFT) &&
  274.         (event->type & GPM_DRAG))
  275.         _move_window(event);
  276.     }
  277.  
  278.     if ((event->buttons & GPM_B_LEFT) && (event->type & GPM_UP)) {
  279.     _xoffset = 0;
  280.     _moving_win = FALSE;
  281.     _moving_idx = -1;
  282.     }
  283. }
  284.  
  285. void _handle_window(Gpm_Event *event)
  286. {
  287.     int findidx = _get_window_index(event);
  288.  
  289.     _top_window_link();
  290.     _cur_window = findidx;
  291.  
  292.     while(_wintree->next) {
  293.     if ((_wintree->index == _cur_window) &&
  294.         (_cur_window != -1)) {
  295.         _handle_window_coords(event);
  296.         return;
  297.     }
  298.  
  299.     _wintree = _wintree->next;
  300.     }
  301. }
  302.  
  303. WINDOW *Win_CreateWindow(int x, int y, int w, int h, char *title, int mode,
  304.     void *callback)
  305. {
  306.     WINDOW *ourwin;
  307.     int idx;
  308.  
  309.     _bottom_window_link();
  310.  
  311.     if (_wintree->prev)
  312.     idx = _wintree->prev->index + 1;
  313.     else
  314.     idx = 1;
  315.  
  316.     _has_win = TRUE;
  317.  
  318.     _wintree->title = (char *) malloc(strlen(title));
  319.     _wintree->mode = mode;
  320.     _wintree->index = idx;
  321.     _wintree->callback = callback;
  322.     strcpy(_wintree->title, title);
  323.  
  324.     _create_window(x, y, w, h, title, mode);
  325.     ourwin = _wintree->workwin;
  326.  
  327.     _add_window_link();
  328.  
  329.     return(ourwin);
  330. }
  331.